using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Microsoft.Extensions.Logging;
using System.Text.Json;
using System.Text.RegularExpressions;
using CKY.AgentPlatform.PromptTemplates.Dto;
using CKY.AgentPlatform.PromptTemplates;

namespace CKY.AgentPlatform.PromptTemplates
{
    /// <summary>
    /// 提示词模板管理应用服务
    /// </summary>
    public class PromptTemplateAppService : ApplicationService, IPromptTemplateAppService
    {
        private readonly IRepository<PromptTemplate, Guid> _templateRepository;
        private readonly ILogger<PromptTemplateAppService> _logger;

        public PromptTemplateAppService(
            IRepository<PromptTemplate, Guid> templateRepository,
            ILogger<PromptTemplateAppService> logger)
        {
            _templateRepository = templateRepository;
            _logger = logger;
        }

        /// <summary>
        /// 获取模板列表
        /// </summary>
        /// <param name="input">查询参数</param>
        /// <returns>模板列表</returns>
        public async Task<PagedResultDto<PromptTemplateDto>> GetListAsync(GetPromptTemplateListInput input)
        {
            var query = await _templateRepository.GetQueryableAsync();

            // 应用过滤条件
            if (!string.IsNullOrWhiteSpace(input.Filter))
            {
                query = query.Where(t =>
                    t.Name.Contains(input.Filter) ||
                    t.Description.Contains(input.Filter) ||
                    t.Category.ToString().Contains(input.Filter)
                );
            }

            if (input.IsActive.HasValue)
            {
                query = query.Where(t => t.IsActive == input.IsActive.Value);
            }

            if (input.IsSystem.HasValue)
            {
                query = query.Where(t => t.IsSystem == input.IsSystem.Value);
            }

            if (!string.IsNullOrWhiteSpace(input.Category))
            {
                if (Enum.TryParse<TemplateCategory>(input.Category, true, out var category))
                {
                    query = query.Where(t => t.Category == category);
                }
            }

            if (input.Tags != null && input.Tags.Length > 0)
            {
                query = query.Where(t => input.Tags.Any(tag => t.Tags.Contains(tag)));
            }

            // 获取总数
            var totalCount = await AsyncExecuter.CountAsync(query);

            // 应用排序和分页
            query = query.OrderByDescending(t => t.IsSystem)
                       .ThenByDescending(t => t.Version)
                       .ThenBy(t => t.Name)
                       .Skip(input.SkipCount)
                       .Take(input.MaxResultCount);

            var templates = await AsyncExecuter.ToListAsync(query);
            var templateDtos = ObjectMapper.Map<List<PromptTemplate>, List<PromptTemplateDto>>(templates);

            return new PagedResultDto<PromptTemplateDto>(
                totalCount,
                templateDtos
            );
        }

        /// <summary>
        /// 获取模板详情
        /// </summary>
        /// <param name="id">模板ID</param>
        /// <returns>模板详情</returns>
        public async Task<PromptTemplateDto> GetAsync(Guid id)
        {
            var template = await _templateRepository.GetAsync(id);
            return ObjectMapper.Map<PromptTemplate, PromptTemplateDto>(template);
        }

        /// <summary>
        /// 创建模板
        /// </summary>
        /// <param name="input">创建参数</param>
        /// <returns>创建的模板</returns>
        public async Task<PromptTemplateDto> CreateAsync(CreatePromptTemplateInput input)
        {
            // 验证模板内容
            ValidateTemplateContent(input.Content);

            // Parse category string to enum
            if (!Enum.TryParse<TemplateCategory>(input.Category, true, out var category))
            {
                category = TemplateCategory.Custom; // Default to Custom if parsing fails
            }

            var template = new PromptTemplate(
                GuidGenerator.Create(),
                input.Name,
                input.Description,
                input.Content,
                category
            );

            // Set additional properties
            if (!Enum.TryParse<PromptTemplateType>(input.TemplateType, true, out var templateType))
            {
                templateType = PromptTemplateType.CustomTemplate; // Default to CustomTemplate if parsing fails
            }
            template.TemplateType = templateType;
            template.Tags = string.Join(",", input.Tags ?? Array.Empty<string>());

            await _templateRepository.InsertAsync(template);

            _logger.LogInformation("创建新提示词模板: {TemplateId}, 名称: {Name}", template.Id, template.Name);

            return ObjectMapper.Map<PromptTemplate, PromptTemplateDto>(template);
        }

        /// <summary>
        /// 更新模板
        /// </summary>
        /// <param name="id">模板ID</param>
        /// <param name="input">更新参数</param>
        /// <returns>更新后的模板</returns>
        public async Task<PromptTemplateDto> UpdateAsync(Guid id, UpdatePromptTemplateInput input)
        {
            var template = await _templateRepository.GetAsync(id);

            // 验证模板内容
            if (input.TemplateContent != template.Template)
            {
                ValidateTemplateContent(input.TemplateContent);
            }

            template.Name = input.Name;
            template.Description = input.Description;
            template.Template = input.TemplateContent;
            if (!Enum.TryParse<PromptTemplateType>(input.Type, true, out var templateType))
            {
                templateType = PromptTemplateType.CustomTemplate; // Default to CustomTemplate if parsing fails
            }
            template.TemplateType = templateType;
            template.Tags = string.Join(",", input.Tags ?? Array.Empty<string>());

            // Parameters handling would need to be implemented based on domain requirements
            // template.Parameters = input.Parameters;

            await _templateRepository.UpdateAsync(template);

            _logger.LogInformation("更新提示词模板: {TemplateId}, 名称: {Name}", template.Id, template.Name);

            return ObjectMapper.Map<PromptTemplate, PromptTemplateDto>(template);
        }

        /// <summary>
        /// 删除模板
        /// </summary>
        /// <param name="id">模板ID</param>
        public async Task DeleteAsync(Guid id)
        {
            var template = await _templateRepository.GetAsync(id);
            await _templateRepository.DeleteAsync(template);

            _logger.LogInformation("删除提示词模板: {TemplateId}, 名称: {Name}", template.Id, template.Name);
        }

        /// <summary>
        /// 渲染模板
        /// </summary>
        /// <param name="input">渲染参数</param>
        /// <returns>渲染结果</returns>
        public async Task<PromptTemplateRenderResultDto> RenderAsync(RenderPromptTemplateInput input)
        {
            var template = await _templateRepository.GetAsync(input.TemplateId);

            try
            {
                // Simple template rendering - would need to implement proper template engine
                var renderedContent = template.Template;
                if (input.Variables != null)
                {
                    var variablesDict = input.Variables as Dictionary<string, object>;
                    if (variablesDict != null)
                    {
                        foreach (var variable in variablesDict)
                        {
                            renderedContent = renderedContent.Replace($"{{{variable.Key}}}", variable.Value?.ToString() ?? "");
                        }
                    }
                }

                return new PromptTemplateRenderResultDto
                {
                    RenderedContent = renderedContent,
                    IsSuccess = true,
                    UsedParameters = input.Variables as Dictionary<string, object> ?? new Dictionary<string, object>(),
                    Timestamp = DateTime.UtcNow
                };
            }
            catch (Exception ex)
            {
                return new PromptTemplateRenderResultDto
                {
                    RenderedContent = "",
                    IsSuccess = false,
                    Error = ex.Message,
                    Timestamp = DateTime.UtcNow
                };
            }
        }

        /// <summary>
        /// 复制模板
        /// </summary>
        /// <param name="input">复制参数</param>
        /// <returns>新模板</returns>
        public async Task<PromptTemplateDto> CopyAsync(CopyPromptTemplateInput input)
        {
            var sourceTemplate = await _templateRepository.GetAsync(input.SourceTemplateId);

            var newTemplate = new PromptTemplate(
                GuidGenerator.Create(),
                input.NewName ?? $"{sourceTemplate.Name}_副本",
                input.NewDescription ?? sourceTemplate.Description,
                sourceTemplate.Template,
                sourceTemplate.Category
            );

            await _templateRepository.InsertAsync(newTemplate);

            _logger.LogInformation("复制提示词模板: {SourceId} -> {NewId}, 名称: {Name}", input.SourceTemplateId, newTemplate.Id, newTemplate.Name);

            return ObjectMapper.Map<PromptTemplate, PromptTemplateDto>(newTemplate);
        }

        /// <summary>
        /// 获取模板使用统计
        /// </summary>
        /// <returns>统计信息</returns>
        public async Task<PromptTemplateStatisticsDto> GetStatisticsAsync()
        {
            var templates = await _templateRepository.GetListAsync();

            return new PromptTemplateStatisticsDto
            {
                TotalTemplates = templates.Count,
                ActiveTemplates = templates.Count(t => t.IsActive),
                SystemTemplates = templates.Count(t => t.IsSystem),
                UserTemplates = templates.Count(t => !t.IsSystem),
                TemplatesByCategory = templates
                    .GroupBy(t => t.Category)
                    .ToDictionary(g => g.Key.ToString(), g => g.Count()),
                Timestamp = DateTime.UtcNow
            };
        }

        /// <summary>
        /// 创建模板版本
        /// </summary>
        /// <param name="input">版本信息</param>
        /// <returns>新版本模板</returns>
        public async Task<PromptTemplateDto> CreateVersionAsync(CreatePromptTemplateVersionInput input)
        {
            var currentTemplate = await _templateRepository.GetAsync(input.TemplateId);

            var newTemplate = new PromptTemplate(
                GuidGenerator.Create(),
                currentTemplate.Name,
                input.Description ?? currentTemplate.Description,
                currentTemplate.Template,
                currentTemplate.Category
            );

            // 设置为新版本
            newTemplate.SetVersion(input.NewVersion);
            newTemplate.SetParentTemplateId(currentTemplate.Id);

            await _templateRepository.InsertAsync(newTemplate);

            _logger.LogInformation("创建模板版本: {ParentId} -> {NewId}, 版本: {Version}", input.TemplateId, newTemplate.Id, input.NewVersion);

            return ObjectMapper.Map<PromptTemplate, PromptTemplateDto>(newTemplate);
        }

        /// <summary>
        /// 验证模板内容
        /// </summary>
        /// <param name="content">模板内容</param>
        private void ValidateTemplateContent(string content)
        {
            if (string.IsNullOrWhiteSpace(content))
            {
                throw new ArgumentException("模板内容不能为空");
            }

            // 检查模板语法
            var parameterRegex = new Regex(@"\{\{(\w+)\}\}");
            var matches = parameterRegex.Matches(content);

            foreach (Match match in matches)
            {
                var parameterName = match.Groups[1].Value;
                if (string.IsNullOrWhiteSpace(parameterName))
                {
                    throw new ArgumentException($"模板参数名称无效: {match.Value}");
                }
            }
        }

        /// <summary>
        /// 获取所有模板分类
        /// </summary>
        /// <returns>分类列表</returns>
        public async Task<List<TemplateCategoryDto>> GetCategoriesAsync()
        {
            var categories = Enum.GetValues<TemplateCategory>()
                .Select(category => new TemplateCategoryDto
                {
                    Value = (int)category,
                    Name = category.ToString(),
                    DisplayName = GetCategoryDisplayName(category)
                })
                .OrderBy(c => c.Value)
                .ToList();

            return await Task.FromResult(categories);
        }

        /// <summary>
        /// 获取分类显示名称
        /// </summary>
        /// <param name="category">分类枚举</param>
        /// <returns>显示名称</returns>
        private string GetCategoryDisplayName(TemplateCategory category)
        {
            return category switch
            {
                TemplateCategory.General => "通用对话",
                TemplateCategory.CodeGeneration => "代码生成",
                TemplateCategory.ContentCreation => "文本创作",
                TemplateCategory.DataAnalysis => "数据分析",
                TemplateCategory.Translation => "翻译",
                TemplateCategory.Summarization => "摘要总结",
                TemplateCategory.QnA => "问答系统",
                TemplateCategory.CustomerSupport => "客服支持",
                TemplateCategory.Education => "教育培训",
                TemplateCategory.Custom => "自定义",
                _ => category.ToString()
            };
        }
    }
}